/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Server.domain;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Ripper
 */
public class Projectile implements WorldOccupant
{
    private double x;
    private double y;
    private int hitboxradius;
    private double rotation;
    private long movementSpeed;
    private long maynextmoveat;
    private GameLevel gamelevel;
    private int looktype;
    private int id;
    private int flydistance;
    private Entity source;
    
    private double originalX;
    private double originalY;
    
    private boolean active;
    
    private boolean physicalProjectile;

    public Projectile(GameLevel gamelevel, Entity parent, double x, double y, int hitboxradius, 
            double rotation, long movementSpeed, 
            int looktype, int id, int flydist, boolean physical) {
        this.x = x;
        this.y = y;
        this.hitboxradius = hitboxradius;
        this.rotation = rotation;
        this.movementSpeed = movementSpeed;
        this.gamelevel = gamelevel;
        this.looktype = looktype;
        this.id = id;
        this.source = parent;
        this.flydistance = flydist;
        
        this.maynextmoveat = System.currentTimeMillis();
        
        active = true;
        physicalProjectile = physical;
        
        originalX = x;
        originalY = y;
    }
    
    public void update()
    {
        move();
        
        //check if it hit anything (player? mob?)
        List<Entity> possibleTargets = new ArrayList<Entity>();
        if(source instanceof Player)
        {
            for(Mob m: getGamelevel().getMonsters())
            {
                possibleTargets.add(m);
            }
        }
        else if(source instanceof Mob)
        {
            for(Player p: getGamelevel().getPlayers())
            {
                possibleTargets.add(p);
            }
        }
        
        for(Entity e: possibleTargets)
        {
            if(MathHelper.getDistanceBetween(this, e) < getHitboxradius()+e.getHitboxradius())
            {
                active = false;
                if(source instanceof Player)
                {
                    getGamelevel().playerAttacks((Player)source);
                }
                if(physicalProjectile)
                {
                    source.dealPhysicalDamageToEntity(e, true);
                }
                else
                {
                    source.dealMagicalDamageToEntity(e);
                }
                if(source instanceof Player)
                {
                    getGamelevel().playerDoneAttacking();
                }
            }
        }
        
        //TODO: check if it hit a wall
        if(MathHelper.getDistanceBetween(this, originalX, originalY) > flydistance)
        {
            active = false;
        }
    }
    
    public void move()
    {
        if(maynextmoveat <= System.currentTimeMillis())
        {
            x += Math.cos(rotation) * 10;
            y += Math.sin(rotation) * 10;
            
            maynextmoveat = System.currentTimeMillis() + (100000 / getMovementSpeed());
        }
    }
    
    public boolean isActive()
    {
        return active;
    }

    @Override
    public int getHitboxradius() 
    {
        return hitboxradius;
    }

    @Override
    public void setHitboxradius(int hitboxradius) 
    {
        this.hitboxradius = hitboxradius;
    }

    @Override
    public double getX() 
    {
        return x;
    }

    @Override
    public void setX(double x) 
    {
        this.x = x;
    }

    @Override
    public double getY() 
    {
        return y;
    }

    @Override
    public void setY(double y) 
    {
        this.y = y;
    }

    public GameLevel getGamelevel() {
        return gamelevel;
    }

    public void setGamelevel(GameLevel gamelevel) {
        this.gamelevel = gamelevel;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getLooktype() {
        return looktype;
    }

    public void setLooktype(int looktype) {
        this.looktype = looktype;
    }

    public long getMovementSpeed() {
        return movementSpeed;
    }

    public void setMovementSpeed(long movementSpeed) {
        this.movementSpeed = movementSpeed;
    }

    public double getRotation() {
        return rotation;
    }

    public void setRotation(double rotation) {
        this.rotation = rotation;
    }

    public Entity getSource() {
        return source;
    }

    public void setSource(Entity source) {
        this.source = source;
    }

    public String getNecessaryInformation() 
    {
        String data = ""+getLocationData()+",mvspd:"+getMovementSpeed()+",looktype:"+getLooktype()+",rot:"+getRotation();
        
        return data;
    }
    
    public String getLocationData()
    {
        return "prj_id:"+id+",x:"+getX()+",y:"+getY();
    }
}
